package com.ljk.studywebsocket.config2;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.socket.TextMessage;

import javax.websocket.*;
import javax.websocket.RemoteEndpoint.Async;
import javax.websocket.RemoteEndpoint.Basic;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.net.URI;
import java.security.Principal;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * ws://localhost:8080/func2/ws
 * @author ljk
 * @since 2023-01-10 20:19
 */
@ServerEndpoint("/func2/ws") // API
@RestController
@Slf4j
public class TestWebSocket {


    private static final ConcurrentHashMap<String, Session> sessionMap = new ConcurrentHashMap<>();

    /**
     * 打开连接
     *
     * @param session 会话
     * @throws Exception 异常
     */
    @OnOpen
    public void onOpen(Session session) throws Exception {
        log.info("客户端{}接入", session.getId());
        sendMessage(String.format("您已接入通讯,当前在线数:%d", sessionMap.size() + 1), session);
//        sendMessage(printSession(session), session);
        sendMessage("分配到的ID:" + session.getId(), session);
        sendAllMessage("检测到[" + session.getId() + "]已上线");
        sessionMap.put(session.getId(), session);
    }

    /**
     * 关闭连接
     */
    @OnClose
    public void onClose(Session session) {
        log.info("客户端{}关闭连接", session.getId());
        sessionMap.remove(session.getId());
        sendAllMessage("检测到[" + session.getId() + "]已下线,剩余在线数:" + sessionMap.size());
        try {
            session.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 接收消息
     *
     * @param message 消息
     * @param session 会话
     */
    @OnMessage
    public void onMessage(String message, Session session) throws Exception {
        log.info("接收客户端消息:{}", message);
        message = String.format("[%s]说:%s", session.getId(), message);
        sendAllMessage(message);
    }

    /**
     * 报错
     *
     * @param session 会话
     * @param error   错误
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("连接{}报错,移除连接,错误信息:{}", session.getId(), error.getMessage());
        sessionMap.remove(session.getId());
    }

    /**
     * 给指定的人发消息
     *
     * @param message 会话
     * @throws Exception 异常
     */
    public void sendMessage(String message, Session session) throws Exception {
        if (session == null || message == null) {
            return;
        }
        if (session.isOpen()) {
            session.getBasicRemote().sendText(message);
        }
    }

    /**
     * 给当前在线的所有人发信息
     *
     * @param message
     * @author ljk
     * @since 2023-01-07 16:10
     */
    public void sendAllMessage(String message) {
        sessionMap.forEach((k, v) -> {
            try {
                // 发送消息
                v.getBasicRemote().sendText(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }

    /**
     * 给当前在线的其他人发信息
     *
     * @param message
     * @author ljk
     * @since 2023-01-07 16:10
     */
    public void sendAllMessage(String message, Session session) {
        sessionMap.forEach((k, v) -> {
            if (session.getId().equals(k)) {
                return;
            }
            try {
                // 发送消息
                v.getBasicRemote().sendText(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        });
    }


    private String printSession(Session session) {
        WebSocketContainer container = session.getContainer();
        Set<MessageHandler> messageHandlers = session.getMessageHandlers();
        String protocolVersion = session.getProtocolVersion();
        String negotiatedSubprotocol = session.getNegotiatedSubprotocol();
        List<Extension> negotiatedExtensions = session.getNegotiatedExtensions();
        boolean isSecure = session.isSecure();
        boolean isOpen = session.isOpen();
        long maxIdleTimeout = session.getMaxIdleTimeout();
        int maxBinaryMessageBufferSize = session.getMaxBinaryMessageBufferSize();
        int maxTextMessageBufferSize = session.getMaxTextMessageBufferSize();
        Async asyncRemote = session.getAsyncRemote();
        Basic basicRemote = session.getBasicRemote();
        String id = session.getId();
        URI requestURI = session.getRequestURI();
        Map<String, List<String>> requestParameterMap = session.getRequestParameterMap();
        String queryString = session.getQueryString();
        Map<String, String> pathParameters = session.getPathParameters();
        Map<String, Object> userProperties = session.getUserProperties();
        Principal userPrincipal = session.getUserPrincipal();
        Set<Session> openSessions = session.getOpenSessions();

        StringBuilder sb = new StringBuilder();
        return null;
    }


}
